home *** CD-ROM | disk | FTP | other *** search
/ Computer Select (Limited Edition) / Computer Select.iso / pcmag / v10n16 / menuunit.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1991-08-27  |  4.3 KB  |  166 lines

  1. UNIT MenuUnit;
  2. (**) INTERFACE (**)
  3. USES CRT;
  4. CONST MaxMsgLen = 32;
  5. TYPE
  6.   MessageString = String[MaxMsgLen];
  7.   EntryPointer   = ^EntryType;
  8.   EntryType = OBJECT
  9.     Prev, Next           : EntryPointer;
  10.     XCor, YCor, ChoiceNo : Integer;
  11.     Message              : MessageString;
  12.     CONSTRUCTOR Init(iPr, iNx : EntryPointer; iX, iY,
  13.                   iC : Integer; iM : MessageString);
  14.     PROCEDURE Draw(Selected : Boolean);
  15.     FUNCTION GetChoice : Integer;
  16.   END;
  17.  
  18.   BBMenu = OBJECT
  19.     XCor, YCor, Wid, Choices : Integer;
  20.     FirstEntry, CurEntry     : EntryPointer;
  21.     CONSTRUCTOR Init(iX, iY, iW : Integer);
  22.     DESTRUCTOR Done;
  23.     PROCEDURE AddPrompt(iM : MessageString);
  24.     PROCEDURE Draw;
  25.     FUNCTION GetChoice : Integer;
  26.   END;
  27.  
  28. (**) IMPLEMENTATION (**)
  29.   CONSTRUCTOR BBMenu.Init(iX, iY, iW : Integer);
  30.   BEGIN
  31.     XCor := iX;
  32.     YCor := iY;
  33.     Wid  := iW;
  34.     IF Wid > MaxMsgLen THEN Wid := MaxMsgLen;
  35.     IF xCor+Wid > 80 THEN Wid := 80 - xCor;
  36.     FirstEntry := NIL;
  37.     Choices := 0;
  38.   END;
  39.  
  40.   DESTRUCTOR BBMenu.Done;
  41.   BEGIN
  42.     IF FirstEntry <> NIL THEN
  43.       BEGIN
  44.         FirstEntry^.Prev^.Next := NIL;
  45.         REPEAT
  46.           CurEntry := FirstEntry;
  47.           FirstEntry := FirstEntry^.Next;
  48.           Dispose(CurEntry);
  49.         UNTIL FirstEntry = NIL;
  50.       END;
  51.   END;
  52.  
  53.   PROCEDURE BBMenu.AddPrompt(iM : MessageString);
  54.   VAR EP : EntryPointer;
  55.   BEGIN
  56.     Inc(Choices);
  57.     {pad with spaces}
  58.     FillChar(iM[length(iM)+1], Wid-length(iM), ' ');
  59.     iM[0] := Char(Wid);
  60.     IF FirstEntry = NIL THEN
  61.       BEGIN
  62.         FirstEntry := New(EntryPointer, Init(NIL,
  63.                       NIL, XCor, YCor+Choices-1,
  64.                       Choices, iM));
  65.         FirstEntry^.Next := FirstEntry;
  66.         FirstEntry^.Prev := FirstEntry;
  67.       END
  68.     ELSE
  69.       BEGIN
  70.         EP := New(EntryPointer, Init(FirstEntry^.Prev,
  71.               FirstEntry, XCor, YCor+Choices-1,
  72.               Choices, iM));
  73.         FirstEntry^.Prev^.Next := EP;
  74.         FirstEntry^.Prev := EP;
  75.       END;
  76.   END;
  77.  
  78.   PROCEDURE BBMenu.Draw;
  79.   VAR ro, co : Byte;
  80.   BEGIN
  81.     GotoXY(xCor-1, yCor-1); Write(#218);
  82.     FOR co := 1 to Wid DO Write(#196); Write(#191);
  83.     FOR ro := yCor TO yCor + Choices -1 DO
  84.       BEGIN
  85.         GotoXY(xCor-1, ro); Write(#179);
  86.         GotoXY(xCor+Wid, ro); Write(#179);
  87.       END;
  88.     GotoXY(xCor-1, yCor+Choices); Write(#192);
  89.     FOR co := 1 to Wid DO Write(#196); Write(#217);
  90.     CurEntry := FirstEntry;
  91.     REPEAT
  92.       CurEntry^.Draw(FALSE);
  93.       CurEntry := CurEntry^.Next;
  94.     UNTIL CurEntry = FirstEntry;
  95.   END;
  96.  
  97. CONST
  98.   kEnter = $000D;  kEsc   = $001B;
  99.   kHome  = $4700;  kEnd   = $4F00;  
  100.   kLeft  = $4B00;  kRight = $4D00;
  101.   kDown  = $5000;  kUp    = $4800;
  102.  
  103.   FUNCTION BBMenu.GetChoice : Integer;
  104.   VAR
  105.     SaveX, SaveY : Integer;
  106.     Finished     : Boolean;
  107.     InChar       : Char;
  108.     InWord       : Word;
  109.   BEGIN
  110.     SaveX := WhereX;
  111.     SaveY := WhereY;
  112.     Draw;
  113.     Finished := FALSE;
  114.     REPEAT
  115.       CurEntry^.Draw(TRUE);
  116.       InChar := ReadKey;
  117.       IF (InChar = #0) AND KeyPressed THEN
  118.         BEGIN
  119.           InChar := ReadKey;
  120.           InWord := Word(InChar) SHL 8;
  121.         END
  122.       ELSE InWord := Ord(InChar);
  123.       CurEntry^.Draw(FALSE);
  124.       CASE InWord OF
  125.         kLeft, kUp    : CurEntry := CurEntry^.Prev;
  126.         kRight, kDown : CurEntry := CurEntry^.Next;
  127.         kHome         : CurEntry := FirstEntry;
  128.         kEnd          : CurEntry := FirstEntry^.Prev;
  129.         kEsc : BEGIN
  130.                 Finished:= True;
  131.                 GetChoice := 0;
  132.               END;
  133.         kEnter : BEGIN
  134.                 Finished := True;
  135.                 GetChoice := CurEntry^.GetChoice;
  136.               END;
  137.       END;
  138.     UNTIL Finished;
  139.     GotoXY(SaveX, SaveY);
  140.   END;
  141.  
  142.   CONSTRUCTOR EntryType.Init(iPr, iNx : EntryPointer;
  143.                 iX, iY, iC : Integer;
  144.                 iM : MessageString);
  145.   BEGIN
  146.     Prev     := iPr;
  147.     Next     := iNx;
  148.     XCor     := iX;
  149.     YCor     := iY;
  150.     ChoiceNo := iC;
  151.     Message  := iM;
  152.   END;
  153.  
  154.   PROCEDURE EntryType.Draw(Selected : Boolean);
  155.   BEGIN
  156.     IF Selected THEN TextAttr := $70
  157.     ELSE TextAttr := $07;
  158.     GotoXY(XCor, YCor);
  159.     Write(Message);
  160.   END;
  161.  
  162.   FUNCTION EntryType.GetChoice : Integer;
  163.   BEGIN GetChoice := ChoiceNo; END;
  164.  
  165. END.
  166.